#ifndef FIFO_H_
#define FIFO_H_

#include <stdint.h>

typedef struct {
	uint8_t _tail;
	uint8_t _head;
	uint8_t* _buffer;
} FIFO_t;

typedef struct {
	uint8_t _tail;
	uint8_t _head;
	uint8_t _buffer[64];
} FIFO64_t;

typedef struct {
	uint8_t _tail;
	uint8_t _head;
	uint8_t _buffer[128];
} FIFO128_t;

#define FIFO_available(fifo)	(fifo._tail != fifo._head)

#define FIFO_read(fifo, size)	( FIFO_available(fifo) ? (fifo._buffer[(fifo._tail = (fifo._tail+1)&(size-1))]) : (fifo._buffer[fifo._tail]) )

#define FIFO_write(fifo, data, size) {															\
	uint8_t tmphead = ( fifo._head + 1 ) & (size-1); 	/* calculate buffer index */			\
	if(tmphead != fifo._tail)							/* if buffer is full, return false */	\
		fifo._head = tmphead;							/* store new index */					\
	fifo._buffer[tmphead] = data;						/* store data in buffer */				\
}

#endif /*FIFO_H_*/
